package io.xxx.xbutler.core.check;

import com.alibaba.fastjson2.JSONObject;
import io.xxx.xbutler.client.ProductClient;
import io.xxx.xbutler.constant.Formats;
import io.xxx.xbutler.domain.Product;
import io.xxx.xbutler.domain.Store;
import io.xxx.xbutler.domain.task.*;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;

@Slf4j
@Order(50)
@Component
public class ProductChecker implements Checker {

    @Resource
    protected ProductClient productClient;

    @Override
    public CheckError check(PushContext context) {
        Task task = context.getTask();
        Store store = context.getStore();
        List<TaskItem> taskItems = context.getTaskItems();
        for (TaskItem taskItem : taskItems) {
            if (!taskItem.isProduct() || !taskItem.assign(MessageType.MINI_PROGRAM, ContentType.PRODUCT_VENUE)) {
                continue;
            }

            if (taskItem.isProduct()) {
                JSONObject content = taskItem.getContent();
                String skuSn = content.getString("skuSn");
                LocalDateTime now = LocalDateTime.now();
                CheckError error = checkProduct(task, taskItem, store, skuSn, now);
                if (error != null) return error;
            }
        }
        return null;
    }

    /**
     * 检查商品是否存在、商品是否限售、商品与门店的经营单元是否匹配
     */
    protected CheckError checkProduct(Task task, TaskItem taskItem, Store store, String skuSn, LocalDateTime now) {
        Product product = productClient.getSaleProduct(store.getId(), skuSn, now);
        if (product == null) {
            CheckError error = CheckError.ProductSaleNotFound;
            log.error(getLogMessage(error.getErrorMessage(), task, taskItem, store, skuSn, now));
            return error;
        }

        if (product.isLimitSale()) {
            CheckError error = CheckError.ProductSaleLimited;
            log.info(getLogMessage(error.getErrorMessage(), task, taskItem, store, skuSn, now));
            return error;
        }

        Set<Long> productBusinessUnitIds = product.getBusinessUnitIds();
        if (productBusinessUnitIds != null && !productBusinessUnitIds.contains(task.getBusinessUnitId())) {
            CheckError error = CheckError.ProductBusinessUnitNotMatch;
            log.info(getLogMessage(error.getErrorMessage(), task, taskItem, store, skuSn, now));
            taskItem.setError(error);
        }
        return null;
    }

    private String getLogMessage(String message, Task task, TaskItem taskItem, Store store, String skuSn, LocalDateTime dateTime) {
        return String.format("%s[taskId:%d, taskItemId:%d, storeId:%d, storeCode:%s, skuSn:%s, date:%s]",
                message, task.getId(), taskItem.getId(), store.getId(), store.getCode(), skuSn, dateTime.format(Formats.DATETIME_FORMATTER));
    }

    @Override
    public boolean supports(PushContext context) {
        return context.getStore() != null;
    }
}
